home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
flc2.arc
/
FLEXLIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-07
|
23KB
|
1,031 lines
/*
flexlist.c
10-4-90
Homogeneous-heterogeneous
hybrid stack-queue-list-array generic class.
ANSI C
Copyright 1990
John W. Small
All rights reserved
PSW / Power SoftWare
P.O. Box 10072,
McLean, Virginia 22102 8072
(703) 759-3838
*/
#include <flexlist.h> /* <stddef.h> size_t */
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memcpy(), memset() */
/* String variant FlexNode virtual functions */
/*
FNnew() is called by FlexList functions (primitives)
that need to allocate new variant length FlexNodes,
e.g. FLpushD(), FLinsQD(), FLinsD(), FLinsSortD().
A pointer to the data to be placed in the new node
is passed to FNnew(). Your FNnew() function must
decide how large that data is and allocate a new
FlexNode big enough to hold that data, i.e.
FlexN N = malloc(sizeof(FlexNode) +
sizeofYourData - 1).
Your FNnew() function must also copy that data to
the new node. "D" is never NULL!
Please note that FNnew() could call a known function
pointer (function) in the data to determine its size.
It could also call another function to copy/
initialize the FlexNode data area from the data.
Data that contains its own functions for interfacing
with itself are called objects. Thus FlexLists can
be made to hold polymorphic objects via the
virtual function table functionology.
Study all four virtual functions FNnew(), FNwrite(),
FNread(), and FNdestruct() for strings and how they
are called by the various FlexList functions to get
a better understanding of variant FlexLists.
*/
static FlexN FNnewStr(const void *D)
{
FlexN N;
size_t i;
for (i = 0; ((char *)D)[i++]; /* no reinit */)
/* null statement */;
if ((N = malloc(sizeof(FlexNode)+i-1)) != FlexN0)
(void) memcpy(N->data,D,i);
return N;
}
/* FNwrite() is called by FLstoreD() to write variant data
to a variant FlexNode. Make sure the new data
doesn't write pass the end of the old. FNwrite()
returns true if the write is successful. "ND" and
"D" are never NULL! */
static int FNwriteStr(void *ND, const void *D)
{
char *nd, *d;
nd = (char *) ND;
d = (char *) D;
while (*nd)
if ((*nd++ = *d++) == '\0')
break;
return 1;
}
/* FNread() is called by FLtopD(), FLnextD(),
FLprevD(), and FLrecallD() to read variant data
from a variant FlexNode. FNread() returns true if
the read is successful. "ND" and "D" are never
NULL! */
static int FNreadStr(const void *ND, void *D)
{
char *nd, *d;
nd = (char *) ND;
d = (char *) D;
while ((*d++ = *nd++) != '\0')
/* null statement */;
return 1;
}
/* FNdestruct() is called by FLclear(), FLdelete() via
Flclear(), FLpopD(), and FLdelD() to destruct
variant data in a FlexNode. Please note that
references to suballocated memory may be copied
to the outgoing data structure instead of being
cloned and then deallocated. You must keep any
scheme straight though. FLclear() always passes
NULL to the second parameter of FNdestruct() via
a call to FLpopD(L,0), however, so any
suballocated memory must be freed in that case!
"ND" is never NULL but "D" can be! */
static int FNdestructStr(void *ND, void *D)
{
char *nd, *d;
nd = (char *)ND;
if ((d = (char *)D) != (char *)0)
while ((*d++ = *nd++) != '\0')
/* null statement */;
return 1;
}
/* Any of the virtual functions can be absent. The FlexList
functions that call them will simply return a failure
indication. Use FNnew0, FNwrite0, FNread0, and/or
FNdestruct0 as zero initializers. */
FlexNodeVFT FlexNodeStrVFT = {
FNnewStr, FNwriteStr, FNreadStr, FNdestructStr };
/* FlexList constructors/destructor - static headers */
#define FLzero(L) memset((void *)(L),0,sizeof(FlexList)-1)
FlexL FLfixed(FlexL L, size_t sizeofNodeData)
{
if (!L)
return L;
(void) FLzero(L);
if (!sizeofNodeData || sizeofNodeData
> FLmaxSizeofNodeData)
return FlexL0;
L->maxNodes = FLmaxMaxNodes;
L->sizeofNodeData = sizeofNodeData;
L->sizeofNode = sizeof(FlexNode)
+ sizeofNodeData - 1;
L->sorted = 1;
return L;
}
FlexL FLunpack(FlexL L, size_t sizeofCell,
unsigned cells, const void *array)
{
if (!L)
return L;
(void) FLzero(L);
if ((sizeofCell > FLmaxSizeofNodeData) ||
!sizeofCell || !cells || !array)
return FlexL0;
L->maxNodes = FLmaxMaxNodes;
L->sizeofNodeData = sizeofCell;
L->sizeofNode = sizeof(FlexNode)
+ sizeofCell - 1;
for (;cells && FLinsQD(L,array); cells--)
array = (char *) array + sizeofCell;
return L;
}
FlexL FLvariant(FlexL L, FlexNVFT vft)
{
if (!L)
return L;
(void) FLzero(L);
if (!vft)
return FlexL0;
L->maxNodes = FLmaxMaxNodes;
L->sorted = 1;
L->vft = vft;
return L;
}
int FLclear(FlexL L)
{
while (FLpopD(L,(void *)0))
/* null statement */;
if (L) if (!L->nodes)
return (L->sorted = 1);
return 0;
}
/* FlexList constructors/destructor - dynamic headers */
/* FlexList headers are flagged as dynamic if and only if
FLDdestruct != NULL. FLDmalloced() is the default
function pointer whenever one isn't specified. */
#pragma argsused
/* ARGSUSED */
static int FLDmalloced(void *LD)
{ /* LD is intentionally unused! */
return 1;
}
static FlexL FLnew(size_t sizeofLocalData,
int (*FLDdestruct)(void *LD))
{
FlexL L;
if (sizeofLocalData > FLmaxSizeofLocalData)
return FlexL0;
L = (FlexL) malloc(sizeof(FlexList) +
sizeofLocalData - 1);
if (L) {
(void) FLzero(L);
if (FLDdestruct)
L->FLDdestruct = FLDdestruct;
else
L->FLDdestruct = FLDmalloced;
}
return L;
}
FlexL FLfixedNew(size_t sizeofNodeData,
size_t sizeofLocalData,
int (*FLDdestruct)(void *LD))
{
FlexL L;
if (!sizeofNodeData || sizeofNodeData >
FLmaxSizeofNodeData)
return FlexL0;
if ((L = FLnew(sizeofLocalData,FLDdestruct))
!= FlexL0) {
L->maxNodes = FLmaxMaxNodes;
L->sizeofNodeData = sizeofNodeData;
L->sizeofNode = sizeof(FlexNode)
+ sizeofNodeData - 1;
L->sorted = 1;
}
return L;
}
FlexL FLunpackNew(size_t sizeofCell,
unsigned cells, const void *array,
size_t sizeofLocalData,
int (*FLDdestruct)(void *LD))
{
FlexL L;
if ((sizeofCell > FLmaxSizeofNodeData) ||
!sizeofCell || !cells || !array)
return FlexL0;
if ((L = FLnew(sizeofLocalData,FLDdestruct))
!= FlexL0) {
L->maxNodes = FLmaxMaxNodes;
L->sizeofNodeData = sizeofCell;
L->sizeofNode = sizeof(FlexNode)
+ sizeofCell - 1;
for (;cells && FLinsQD(L,array); cells--)
array = (char *) array + sizeofCell;
}
return L;
}
FlexL FLvariantNew(FlexNVFT vft,
size_t sizeofLocalData,
int (*FLDdestruct)(void *LD))
{
FlexL L;
if (!vft)
return FlexL0;
if ((L = FLnew(sizeofLocalData,FLDdestruct))
!= FlexL0) {
L->maxNodes = FLmaxMaxNodes;
L->sorted = 1;
L->vft = vft;
}
return L;
}
int FLdelete(FlexL *Lptr)
{
if (!Lptr)
return 0;
if (!(*Lptr)->FLDdestruct)
return 0;
if (!(*((*Lptr)->FLDdestruct))((*Lptr)->data))
return 0;
if (!FLclear(*Lptr))
return 0;
free(*Lptr);
*Lptr = FlexL0;
return 1;
}
/* FlexList header functions */
int FLsetMaxNodes(FlexL L, unsigned maxNodes)
{
if (L)
if (maxNodes >= L->nodes) {
L->maxNodes = maxNodes;
return 1;
}
return 0;
}
int FLsetCompare(FlexL L, int (*compare)
(const void *D1, const void *D2))
{
if (L) {
L->compare = compare;
L->sorted = 0;
return 1;
}
return 0;
}
/* FlexList stack and queue functions */
void * FLpushN(FlexL L, FlexN N)
{
if (!L || !N)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
N->prev = FlexN0;
if ((N->next = L->front) != FlexN0)
N->next->prev = N;
else
L->rear = N;
L->front = N;
L->nodes++;
if (L->curNum)
L->curNum++;
L->sorted = 0;
return N->data;
}
void * FLpushD(FlexL L, const void *D)
{
FlexN N;
if (!L)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
if (L->sizeofNode) { /* fixed size FlexNodes */
if ((N = malloc(L->sizeofNode)) == FlexN0)
return (void *) 0;
if (D)
memcpy(N->data,D,L->sizeofNodeData);
else
memset(N->data,0,L->sizeofNodeData);
}
else if (!L->vft || !D)
return (void *) 0;
else if (!L->vft->FNnew)
return (void *) 0;
else if ((N = (*L->vft->FNnew)(D)) == FlexN0)
return (void *) 0;
N->prev = FlexN0;
if ((N->next = L->front) != FlexN0)
N->next->prev = N;
else
L->rear = N;
L->front = N;
L->nodes++;
if (L->curNum)
L->curNum++;
L->sorted = 0;
return N->data;
}
FlexN FLpopN(FlexL L)
{
FlexN N;
if (!L)
return FlexN0;
if ((N = L->front) == FlexN0)
return FlexN0;
if (L->front == L->rear)
L->rear = FlexN0;
else
N->next->prev = FlexN0;
L->front = N->next;
L->nodes--;
if (L->curNum)
if (!--L->curNum)
L->current = FlexN0;
N->next = N->prev = FlexN0;
return N;
}
int FLpopD(FlexL L, void *D)
{
FlexN N;
if (!L)
return 0;
if ((N = L->front) == FlexN0)
return 0;
if (L->sizeofNodeData) {
if (D)
memcpy(D,N->data,L->sizeofNodeData);
}
else if (!L->vft)
return 0;
else if (!L->vft->FNdestruct)
return 0;
else if (!(*L->vft->FNdestruct)(N->data,D))
return 0;
if (L->front == L->rear)
L->rear = FlexN0;
else
N->next->prev = FlexN0;
L->front = N->next;
L->nodes--;
if (L->curNum)
if (!--L->curNum)
L->current = FlexN0;
free(N);
return 1;
}
void * FLtopD(FlexL L, void *D)
{
if (!L)
return (void *) 0;
if (!L->front)
return (void *) 0;
if (D) if (L->sizeofNodeData)
memcpy(D,L->front->data,L->sizeofNodeData);
else if (!L->vft)
return (void *) 0;
else if (!L->vft->FNread)
return (void *) 0;
else if (!(*L->vft->FNread)(L->front->data,D))
return (void *) 0;
return L->front->data;
}
void * FLinsQN(FlexL L, FlexN N)
{
if (!L || !N)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
N->next = FlexN0;
if (L->rear)
L->rear->next = N;
else
L->front = N;
N->prev = L->rear;
L->rear = N;
L->nodes++;
L->sorted = 0;
return N->data;
}
void * FLinsQD(FlexL L, const void *D)
{
FlexN N;
if (!L)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
if (L->sizeofNode) { /* fixed size FlexNodes */
if ((N = malloc(L->sizeofNode)) == FlexN0)
return (void *) 0;
if (D)
memcpy(N->data,D,L->sizeofNodeData);
else
memset(N->data,0,L->sizeofNodeData);
}
else if (!L->vft || !D)
return (void *) 0;
else if (!L->vft->FNnew)
return (void *) 0;
else if ((N = (*L->vft->FNnew)(D)) == FlexN0)
return (void *) 0;
N->next = FlexN0;
if (L->rear)
L->rear->next = N;
else
L->front = N;
N->prev = L->rear;
L->rear = N;
L->nodes++;
L->sorted = 0;
return N->data;
}
void * FLmkcur(FlexL L, unsigned n)
{
if (!L) return (void *) 0;
if (!n || (n > L->nodes)) { /* out of range */
L->current = 0;
L->curNum = 0;
return (void *) 0;
}
else if (n == L->curNum) /* already there */
return L->current->data;
if (L->current) /* divide list into two parts */
if (n > L->curNum) /* in last half of list */
if (((L->nodes >> 1) + (L->curNum >> 1)) < n)
/* rear closest */
for (L->current = L->rear, L->curNum = L->nodes;
L->curNum > n; L->curNum--)
L->current = L->current->prev;
else /* current closest */
for (;L->curNum < n; L->curNum++)
L->current = L->current->next;
else /* in first half of list */
if ((L->curNum >> 1) < n) /* current closest */
for (;L->curNum > n; L->curNum--)
L->current = L->current->prev;
else /* front closest */
for (L->current = L->front, L->curNum = 1;
L->curNum < n; L->curNum++)
L->current = L->current->next;
else /* consider whole list */
if ((L->nodes >> 1) < n) /* closer to rear */
for (L->current = L->rear, L->curNum = L->nodes;
L->curNum > n; L->curNum--)
L->current = L->current->prev;
else /* closer to front */
for (L->current = L->front, L->curNum = 1;
L->curNum < n; L->curNum++)
L->current = L->current->next;
return L->current->data;
}
void * FLinsN(FlexL L, FlexN N)
{
if (!L || !N)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
if ((N->prev = L->current) == FlexN0) {
if ((N->next = L->front) == FlexN0)
L->rear = N;
else
N->next->prev = N;
L->front = N;
}
else { /* after current */
if ((N->next = L->current->next) == FlexN0)
L->rear = N; /* last node */
else
N->next->prev = N;
L->current->next = N;
}
L->current = N;
L->curNum++;
L->nodes++;
L->sorted = 0;
return N->data;
}
void * FLinsD(FlexL L, const void *D)
{
FlexN N;
if (!L)
return (void *) 0;
if (L->nodes >= L->maxNodes)
return (void *) 0;
if (L->sizeofNode) { /* fixed size FlexNodes */
if ((N = malloc(L->sizeofNode)) == FlexN0)
return (void *) 0;
if (D)
memcpy(N->data,D,L->sizeofNodeData);
else
memset(N->data,0,L->sizeofNodeData);
}
else if (!L->vft || !D)
return (void *) 0;
else if (!L->vft->FNnew)
return (void *) 0;
else if ((N = (*L->vft->FNnew)(D)) == FlexN0)
return (void *) 0;
if ((N->prev = L->current) == FlexN0) {
if ((N->next = L->front) == FlexN0)
L->rear = N;
else
N->next->prev = N;
L->front = N;
}
else { /* after current */
if ((N->next = L->current->next) == FlexN0)
L->rear = N; /* last node */
else
N->next->prev = N;
L->current->next = N;
}
L->current = N;
L->curNum++;
L->nodes++;
L->sorted = 0;
return N->data;
}
void * FLinsSortN(FlexL L, FlexN N)
{
unsigned long low, high;
void *ok;
if (!L || !N)
return (void *) 0;
if (L->nodes >= L->maxNodes || !L->compare)
return (void *) 0;
if (!L->sorted)
(void) FLsort(L,FLcompare0);
low = 1UL;
high = (unsigned long) L->nodes;
while (low <= high)
if ((*L->compare)(FLmkcur(L,
(unsigned)((low+high) >> 1)),
N->data) <= 0)
low = (unsigned long)
(L->curNum + 1);
else
high = (unsigned long)
(L->curNum - 1);
(void) FLmkcur(L,(unsigned)high);
ok = FLinsN(L,N);
L->sorted = 1;
return ok;
}
void * FLinsSortD(FlexL L, const void *D)
{
FlexN N;
unsigned long low, high;
void *ok;
if (!L || !D)
return (void *) 0;
if (L->nodes >= L->maxNodes || !L->compare)
return (void *) 0;
if (L->sizeofNode) { /* fixed size FlexNodes */
if ((N = malloc(L->sizeofNode)) == FlexN0)
return (void *) 0;
memcpy(N->data,D,L->sizeofNodeData);
}
else if (!L->vft)
return (void *) 0;
else if (!L->vft->FNnew)
return (void *) 0;
else if ((N = (*L->vft->FNnew)(D)) == FlexN0)
return (void *) 0;
if (!L->sorted)
(void) FLsort(L,FLcompare0);
low = 1UL;
high = (unsigned long) L->nodes;
while (low <= high)
if ((*L->compare)(FLmkcur(L,
(unsigned)((low+high) >> 1)),
N->data) <= 0)
low = (unsigned long)
(L->curNum + 1);
else
high = (unsigned long)
(L->curNum - 1);
(void) FLmkcur(L,(unsigned)high);
ok = FLinsN(L,N);
L->sorted = 1;
return ok;
}
FlexN FLdelN(FlexL L)
{
FlexN N;
if (!L)
return FlexN0;
if ((N = L->current) == FlexN0)
return FlexN0;
L->current = N->prev;
L->curNum--;
if (N->next)
N->next->prev = N->prev;
else
L->rear = N->prev;
if (N->prev)
N->prev->next = N->next;
else
L->front = N->next;
L->nodes--;
N->next = N->prev = FlexN0;
return N;
}
int FLdelD(FlexL L, void *D)
{
FlexN N;
if (!L)
return 0;
if ((N = L->current) == FlexN0)
return 0;
if (L->sizeofNodeData) {
if (D)
memcpy(D,N->data,L->sizeofNodeData);
}
else if (!L->vft)
return 0;
else if (!L->vft->FNdestruct)
return 0;
else if (!(*L->vft->FNdestruct)(N->data,D))
return 0;
L->current = N->prev;
L->curNum--;
if (N->next)
N->next->prev = N->prev;
else
L->rear = N->prev;
if (N->prev)
N->prev->next = N->next;
else
L->front = N->next;
L->nodes--;
free(N);
return 1;
}
void * FLnextD(FlexL L, void *D)
{
FlexN oldCurrent;
if (!L)
return (void *) 0;
if ((oldCurrent = L->current) != FlexN0)
L->current = L->current->next;
else
L->current = L->front;
if (!L->current) {
L->curNum = 0;
return (void *) 0;
}
if (D) if (L->sizeofNodeData)
memcpy(D,L->current->data,
L->sizeofNodeData);
else if (!L->vft) {
L->current = oldCurrent;
return (void *) 0;
}
else if (!L->vft->FNread) {
L->current = oldCurrent;
return (void *) 0;
}
else if (!(*L->vft->FNread)(L->current->data,D)) {
L->current = oldCurrent;
return (void *) 0;
}
L->curNum++;
return L->current->data;
}
void * FLprevD(FlexL L, void *D)
{
FlexN oldCurrent;
unsigned oldCurNum;
if (!L)
return (void *) 0;
oldCurNum = L->curNum;
if ((oldCurrent = L->current) != FlexN0) {
L->current = L->current->prev;
L->curNum--;
}
else {
L->current = L->rear;
L->curNum = L->nodes;
}
if (!L->current)
return (void *) 0;
if (D) if (L->sizeofNodeData)
memcpy(D,L->current->data,
L->sizeofNodeData);
else if (!L->vft) {
L->curNum = oldCurNum;
L->current = oldCurrent;
return (void *) 0;
}
else if (!L->vft->FNread) {
L->curNum = oldCurNum;
L->current = oldCurrent;
return (void *) 0;
}
else if (!(*L->vft->FNread)(L->current->data,D)) {
L->curNum = oldCurNum;
L->current = oldCurrent;
return (void *) 0;
}
return L->current->data;
}
void * FLfindFirstD(FlexL L, const void *D)
{
unsigned long low, high;
if (!L || !D)
return (void *) 0;
if (!L->compare)
return (void *) 0;
if (L->sorted) {
low = 1UL;
high = (unsigned long) L->nodes;
while (low <= high)
if ((*L->compare)(FLmkcur(L,
(unsigned)((low+high) >> 1)),D) < 0)
low = (unsigned long) (L->curNum + 1);
else
high = (unsigned long) (L->curNum - 1);
if (FLmkcur(L,(unsigned)high+1))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
/* leave at insertion point */
(void) FLmkcur(L,(unsigned)high);
}
else {
(void) FLmkcur(L,0);
while (FLnextD(L,(void *)0))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
}
return (void *) 0;
}
void * FLfindNextD(FlexL L, const void *D)
{
if (!L || !D)
return (void *) 0;
if (!L->compare)
return (void *) 0;
while (FLnextD(L,(void *)0))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
else if (L->sorted)
break;
return (void *) 0;
}
void * FLfindLastD(FlexL L, const void *D)
{
unsigned long low, high;
if (!L || !D)
return (void *) 0;
if (!L->compare)
return (void *) 0;
if (L->sorted) {
low = 1UL;
high = (unsigned long) L->nodes;
while (low <= high)
if ((*L->compare)(FLmkcur(L,
(unsigned)((low+high) >> 1)),D) <= 0)
low = (unsigned long) (L->curNum + 1);
else
high = (unsigned long) (L->curNum - 1);
if (FLmkcur(L,(unsigned)high))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
}
else {
(void) FLmkcur(L,0);
while (FLprevD(L,(void *)0))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
}
return (void *) 0;
}
void * FLfindPrevD(FlexL L, const void *D)
{
if (!L || !D)
return (void *) 0;
if (!L->compare)
return (void *) 0;
while (FLprevD(L,(void *)0))
if (!(*L->compare)(L->current->data,D))
return L->current->data;
else if (L->sorted)
break;
return (void *) 0;
}
int FLsort(FlexL L, int (*compare)
(const void *D1, const void *D2))
{
FlexList tmp;
if (!L)
return 0;
if (L->sorted) {
if (L->compare == compare || !compare)
{ FLmkcur(L,0); return 1; }
}
else if (!L->compare && !compare)
return 0;
if (compare)
L->compare = compare;
if (!L->nodes)
return (L->sorted = 1);
(void) FLzero(&tmp);
tmp.maxNodes = FLmaxMaxNodes;
tmp.sorted = 1;
tmp.compare = L->compare;
while (L->nodes)
(void) FLinsSortN(&tmp,FLpopN(L));
L->front = tmp.front;
L->rear = tmp.rear;
L->nodes = tmp.nodes;
return (L->sorted = 1);
}
int FLstoreD(FlexL L, const void *D, unsigned n)
{
unsigned oldn;
if (!L || !D)
return 0;
if (n > L->nodes || !n && !L->current)
return 0;
if (L->sizeofNodeData) {
if (n) (void) FLmkcur(L,n);
memcpy(L->current->data,D,
L->sizeofNodeData);
}
else if (!L->vft)
return 0;
else if (!L->vft->FNwrite)
return 0;
else {
oldn = L->curNum;
if (n) (void) FLmkcur(L,n);
if (!(*L->vft->FNwrite)(L->current->data,D))
{
(void) FLmkcur(L,oldn);
return 0;
}
}
L->sorted = 0;
return 1;
}
int FLrecallD(FlexL L, void *D, unsigned n)
{
unsigned oldn;
if (!L || !D)
return 0;
if (n > L->nodes || !n && !L->current)
return 0;
if (L->sizeofNodeData) {
if (n) (void) FLmkcur(L,n);
memcpy(D,L->current->data,
L->sizeofNodeData);
}
else if (!L->vft)
return 0;
else if (!L->vft->FNread)
return 0;
else {
oldn = L->curNum;
if (n) (void) FLmkcur(L,n);
if (!(*L->vft->FNread)(L->current->data,D))
{
(void) FLmkcur(L,oldn);
return 0;
}
}
return 1;
}
void * FLpack(FlexL L) /* Only fixed nodes! */
{
long sizeofArray;
char *A, *Ai;
FlexN N;
if (!L) return (void *) 0;
sizeofArray = ((long)L->sizeofNodeData)
* ((long)L->nodes);
if ((sizeofArray <= 0) ||
(sizeofArray > FLmaxSizeofArray))
return (void *) 0;
if ((A = malloc((unsigned) sizeofArray))
== (char *) 0)
return (void *) 0;
for (Ai = A, N = L->front; N; N = N->next,
Ai += L->sizeofNodeData)
memcpy(Ai,N->data,L->sizeofNodeData);
return A;
}
void **FLpackPtrs(FlexL L)
{
long sizeofArray;
void **A;
unsigned Ai;
FlexN N;
if (!L) return (void **) 0;
sizeofArray = sizeof(void *) * ((long)L->nodes + 1);
if ((sizeofArray <= 0) ||
(sizeofArray > FLmaxSizeofArray))
return (void **) 0;
if ((A = malloc((unsigned) sizeofArray))
== (void **) 0)
return (void **) 0;
for (Ai = 0, N = L->front; N; Ai++, N = N->next)
A[Ai] = N->data;
A[Ai] = (void *) 0;
return A;
}